<template>
  <div
    :class="[
      'chart-components-wrap',
      isAnalysis ? 'has-analysis' : 'no-analysis',
    ]"
    v-loading="isLoading"
  >
    <graph
      v-if="graph && !isEmpty"
      ref="graph"
      class="graph-wrap"
      :graph="graph"
      :option="option"
      :resize="resize"
      @variableChange="variableChange"
      @chartClick="chartClick"
    ></graph>
    <div v-if="graph && !isEmpty && isAnalysis" class="analysis-wrap">
      <!--      <div v-html="analysis"></div>-->
      <common-editor-view :value="analysis"></common-editor-view>
    </div>

    <common-empty-data v-if="!isError && isEmpty"></common-empty-data>
    <common-error
      v-if="isError"
      type="failed"
      :message="errorMessage"
      :describe="errorDescribe"
    ></common-error>

    <!--    <common-info-dialog :visible="relationComponent.show" @cancel="closeComponentPage">
          <common-page v-if="relationComponent.show" :title="relationComponent.componentName">
            <el-button slot="header" @click="closeComponentPage">返回</el-button>
            <preview slot="content" :id="relationComponent.componentId" :variable-config="relationComponent.variable">

            </preview>
          </common-page>
        </common-info-dialog>-->

    <common-page
      v-if="
        relationComponent.relationPreviewMode === 'M_TOGGLE' &&
        relationComponent.show
      "
      :title="`${name} - ${relationComponent.componentName}`"
    >
      <el-button slot="header" @click="closeComponentPage">返回</el-button>
      <preview
        slot="content"
        :id="relationComponent.componentId"
        :variable-config="relationComponent.variable"
      >
      </preview>
    </common-page>

    <common-info-dialog
      v-if="relationComponent.relationPreviewMode === 'M_DIALOG'"
      :visible="relationComponent.show"
      @cancel="closeComponentPage"
    >
      <div
        class="relation-graph-preview"
        style="
          width: 100%;
          height: 500px;
          padding: 12px;
          box-sizing: border-box;
        "
      >
        <preview
          :id="relationComponent.componentId"
          :variable-config="relationComponent.variable"
        >
        </preview>
      </div>
    </common-info-dialog>
  </div>
</template>

<script>
import graph from "./index";
import { getChartInstance } from "../configuration";
import { getComponent } from "@/api/screenConfig/dataComponents";
import { getReportsData } from "@/api/screenConfig/dataSet";
import $bus from "../bus/timer";
import { md5 } from "@/utils/aesUtils";
import CommonEditorView from "@/components/CommonEditorView";
import { getAssociatedVariable } from "../utils";
import internal from "stream";

export default {
  name: "Preview",
  props: {
    id: {
      type: [Number, String],
      default: "",
    },
    resize: [Number, String],
    variableConfig: {
      type: Array,
      default: () => [
        /*{
          name: '',
          type: '',
          defaultValue: ''
        }*/
      ],
    },
  },
  components: {
    graph,
    CommonEditorView,
  },
  data() {
    return {
      key: "", // 内部生成唯一标识,解决看板拖入相同图表的问题
      name: "", // 当前图表名称
      isLoading: true, // 是否加载动画
      option: null, // 图表配置项
      graph: null, // 图表组件
      graphType: "", // 图表组件类型
      datasetId: "", // 数据集ID
      instance: null, // 图表实例
      analysis: "", // 维度分析
      config: {
        dataPoolField: {}, // 生成图表配置项 所需 字段配置容器数据
        dataField: [], // 数据集最新的字段
        dataList: [], // 生成图表配置项 所需 的数据 页面临时配置
        dataTotal: 0,
        styleOptionConfig: [], // 生成图表配置项 所需 的图表样式配置
        themeColor: [],
        themeStyle: {}, // 生成图表配置项 所需 全局主题样式
        relationConfig: {}, // 关联详情配置项
      },
      isEmpty: false,
      isError: false,
      errorMessage: "",
      errorDescribe: "",
      lastId: "", // 上一次 保存的id
      lastVariableConfig: "", // 上一次 保存的变量
      relationComponent: {
        show: false,
        componentId: "",
        componentName: "",
        variable: "",
        relationPreviewMode: "M_DIALOG",
      },
      relationBoard: {
        show: false,
        boardId: "",
        boardName: "",
        variable: "",
      },
    };
  },
  watch: {
    id: function () {
      this.lastId = this.id;
      this.handleIdChange();
    },
    variableConfig: {
      handler() {
        if (this.id === this.lastId) {
          if (JSON.stringify(this.variableConfig) === this.lastVariableConfig) {
            // console.warn('变量内容没有变化 不执行数据更新')
          } else {
            this.lastVariableConfig = JSON.stringify(this.variableConfig);
            this.updateComponentData();
          }
        } else {
          // console.warn('ID变化 不执行数据更新')
        }
      },
      deep: true,
    },
  },
  computed: {
    isAnalysis: function () {
      return typeof this.analysis === "string" && this.analysis.length > 0;
    },
  },
  methods: {
    handleIdChange() {
      if (this.id) {
        setTimeout(() => {
          this.$nextTick(() => {
            this.getComponentData();
          });
        }, 100);
      } else {
        console.warn("未获取到ID");
      }
    },
    /**
     * 根据数据ID 获取数据
     * @param id 数据集ID
     * @param isReset 是否重置分页
     * @returns dataList 数据集数据
     */
    getReportsData(id, isReset = true) {
      let variableConfig = this.handleVariable(isReset);

      return new Promise((resolve, reject) => {
        getReportsData({
          datasetId: id,
          dataSetVariableConfig: variableConfig,
        })
          .then((res) => {
            this.isError = false;
            if (res && res.code === 200) {
              let { dataList, dataField, total } = res.data;
              resolve({
                dataField,
                dataList,
                dataTotal: total,
              });
            } else {
              this.isError = true;
              this.errorMessage = "数据加载失败！";
              this.errorDescribe = res.msg;
              resolve({
                dataField: [],
                dataList: [],
                dataTotal: 0,
              });
            }
          })
          .catch((e) => {
            this.isError = true;
            this.errorMessage = "";
            this.errorDescribe = "";
            resolve({
              dataField: [],
              dataList: [],
              dataTotal: 0,
            });
          });
      });
    },
    /**
     * 获取当前组件配置项
     */
    getComponentData() {
      this.isLoading = true;
      getComponent({ id: this.id })
        .then((res) => {
          if (res && res.code === 200) {
            let component = res.data;

            this.name = component.name;
            this.analysis = component.analysis;
            this.graphType = component.chartType;

            this.thrownName(component.name);

            this.datasetId = component.dataset.id;

            try {
              this.config.themeColor = component.theme.split(",");
            } catch (e) {
              this.config.themeColor = [];
            }

            let variableList = getAssociatedVariable(component.dataset);

            this.thrownTimer(component.id, component.refresh);
            this.thrownVariable(
              component.id,
              component.datasetId,
              JSON.stringify(variableList)
            );

            this.instance = getChartInstance(component.chartType);

            this.graph = this.instance.getInfo().component;

            // 处理组件配置项
            try {
              let { styleOption } = JSON.parse(component.chartConfig);

              let styleOptionConfig =
                this.instance._transformStyleOption(styleOption);

              this.config.styleOptionConfig =
                this.instance._mergeStyleOptionConfig(
                  this.instance.getStyleOptionConfig(),
                  styleOptionConfig
                );
            } catch (e) {
              console.error("组件配置项转换异常", e);
            }

            // 处理组件配置的字段
            try {
              let { dataPoolField, relationConfig } = JSON.parse(
                component.pageConfig
              );
              this.config.dataPoolField = dataPoolField;
              this.config.relationConfig = relationConfig;
            } catch (e) {
              console.error("组件配置的字段转换异常", e);
            }

            // 解决数据加载前获取不到分页配置的问题
            this.option = this.instance.getOption(this.config);

            this.isError = false;

            this.$nextTick(() => {
              this.getReportsData(component.dataset.id, true)
                .then((res) => {
                  let { dataList, dataTotal, dataField } = res;
                  this.config.dataField = dataField;
                  this.config.dataList = dataList;
                  this.config.dataTotal = dataTotal;
                })
                .catch((err) => {
                  this.config.dataList = [];
                })
                .finally(() => {
                  this.isLoading = false;
                  this.isEmpty = !(
                    this.config.dataList &&
                    this.config.dataList instanceof Array &&
                    this.config.dataList.length
                  );

                  this.option = this.instance.getOption(this.config);
                });
            });
          } else if (res.code == 511) {
            this.isError = true;
            this.isLoading = false;
            this.errorMessage = "组件加载失败！";
            this.errorDescribe = "关联组件已经被删除!";
          } else {
            this.isError = true;
            this.isLoading = false;
            this.errorMessage = "组件加载失败！";
            this.errorDescribe = res.msg;
          }
        })
        .catch((err) => {
          this.isError = true;
          this.isLoading = false;
          this.errorMessage = "组件加载失败！";
          this.errorDescribe = err.msg;
        });
    },

    updateComponentData() {
      this.isLoading = true;
      this.getReportsData(this.datasetId, false)
        .then((res) => {
          let { dataList, dataTotal } = res;
          this.config.dataList = dataList;
          this.config.dataTotal = dataTotal;
        })
        .catch((err) => {
          this.config.dataList = [];
        })
        .finally(() => {
          this.isLoading = false;

          this.isEmpty = !(
            this.config.dataList &&
            this.config.dataList instanceof Array &&
            this.config.dataList.length
          );

          this.option = this.instance.getOption(this.config);
        });
    },
    /**
     * 抛出定时器 配置
     * @param id 报表组件ID
     * @param interval 定时时间间隔
     */
    thrownTimer(id, interval) {
      if (interval > 0) {
        this.key = md5(`${id}_${interval}_${new Date().getTime()}`);
        $bus.$emit("handle-timer", {
          id,
          key: this.key,
          interval,
        });
      }
    },
    /**
     * 抛出局部变量
     * @param id 报表组件ID
     * @param datasetId 数据集ID
     * @param variable 变量配置项
     */
    thrownVariable(id, datasetId, variable) {
      this.$emit("variable", {
        id,
        datasetId,
        variable,
      });
    },
    thrownName(name) {
      this.$emit("name", {
        id: this.id,
        name,
      });
    },
    /**
     * 数据刷新方法
     */
    refresh() {
      this.handleIdChange();
    },
    /**
     * 处理入参
     * @param isReset 是否重置分页参数
     * @returns {*[]}
     */
    handleVariable(isReset = true) {
      let variable = [],
        variableConfig = [];
      let graph = this.$refs.graph;
      // get

      if (graph) variable = graph.getVariable(isReset);

      // check
      if (
        this.variableConfig &&
        this.variableConfig instanceof Array &&
        this.variableConfig.length
      ) {
        variableConfig = this.variableConfig.reduce((r, c) => {
          r.push({ ...c });
          return r;
        }, []);
      }

      // merge
      if (variable.length && variableConfig.length) {
        variable.forEach((v) => {
          let index = variableConfig.findIndex((vc) => vc.name === v.name);
          if (index === -1) {
            variableConfig.push(v);
          } else {
            variableConfig[index].defaultValue = v.defaultValue;
          }
        });
      } else if (variable.length || variableConfig.length) {
        variableConfig = variableConfig.concat(variable);
      }

      return variableConfig;
    },
    variableChange(v) {
      this.updateComponentData();
    },
    chartClick(e) {
      if (this.config.relationConfig) {
        try {
          let {
            relationType,
            assignType,
            variable,
            componentId,
            componentName,
            relationPreviewMode,
            triggerField,
          } = this.config.relationConfig;

          if (this.graphType === "table-list") {
            if (triggerField) {
              if (e.name === triggerField) {
              } else {
                console.log("配置字段: ", e.name);
                console.log("触发字段: ", triggerField);
                return;
              }
            } else {
              console.log("未配置触发字段!");
              return;
            }
          }

          if ("getClickData" in this.instance) {
            // 点击的数据
            let { label, value } = this.instance.getClickData(e);
            // 暂时默认为类目 类目只传key
            let content = assignType === "A_VALUE" ? value : label;

            // 表格单独判断 只传数值
            if (this.graphType === "table-list") {
              content = value;
            }

            // relationType : T_COMPONENT 关联组件 T_BOARD 关联看板
            // assignType: A_CATEGORY 类目 A_VALUE 数值
            if (relationType === "T_COMPONENT") {
              this.relationComponent.componentId = componentId;
              this.relationComponent.componentName = componentName;
              this.relationComponent.relationPreviewMode =
                relationPreviewMode || "M_DIALOG";

              console.log(variable);
              if (variable instanceof Array) {
                this.relationComponent.variable = variable.reduce((r, c, i) => {
                  r.push({
                    name: c,
                    type: "string",
                    defaultValue:
                      content instanceof Array ? content[i] : content,
                  });
                  return r;
                }, []);
              } else {
                this.relationComponent.variable = [
                  {
                    name: variable,
                    type: "string",
                    defaultValue: content,
                  },
                ];
              }
              this.relationComponent.show = true;
            }
            if (relationType === "T_BOARD") {
            }
          } else {
            console.log("no getClickData");
          }
        } catch (e) {}
      } else {
        console.log("未配置关联！");
      }
    },
    closeComponentPage() {
      this.relationComponent.show = false;
    },
  },
  beforeDestroy() {
    $bus.$off("updateChartData");
  },
  mounted() {
    this.lastId = this.id;
    this.lastVariableConfig = JSON.stringify(this.variableConfig);

    this.handleIdChange();
    $bus.$on("updateChartData", (key) => {
      if (key === this.key) {
        this.updateComponentData();
      }
    });
  },
};
</script>

<style scoped lang="scss">
.chart-components-wrap {
  width: 100%;
  height: 100%;

  .graph-wrap {
  }

  .analysis-wrap {
    padding: 0 18px;
    box-sizing: border-box;
  }

  .relation-graph-preview {
    width: 500px;
    height: 400px;
  }
}

.has-analysis {
  overflow-y: scroll;
  overflow-x: hidden;

  .graph-wrap {
    height: calc(100% - 160px);
  }
}

.no-analysis {
  // overflow: hidden;

  .graph-wrap {
    height: 100%;
  }
}
</style>
